package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.StringUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.query.QuestionAdminPageQuery;
import com.tianji.learning.domain.query.QuestionPageQuery;
import com.tianji.learning.domain.vo.QuestionAdminVO;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.learning.service.IInteractionReplyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author liuchun
 * @since 2024-08-30
 */
@Service
@Slf4j
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {


    @Autowired
    private UserClient userClient;

    @Autowired
    private InteractionReplyMapper replyMapper;

    @Autowired
    private IInteractionReplyService replyService;

    @Autowired
    private SearchClient searchClient;

    @Autowired
    private CourseClient courseClient;

    @Autowired
    private CatalogueClient catalogueClient;
    @Autowired
    private CategoryCache categoryCache;

    /**
     * 新增提问
     * @param questionFormDTO
     */
    @Override
    public void saveQuestion(QuestionFormDTO questionFormDTO) {
        //获取登录用户
        Long userId = UserContext.getUser();
        //数据转换
        InteractionQuestion question = BeanUtils.toBean(questionFormDTO, InteractionQuestion.class);
        //补充数据
        question.setUserId(userId);
        //保存问题
        save(question);
    }

    /**
     * 修改提问
     * @param id
     * @param questionFormDTO
     */
    @Override
    public void updateQuestion(Long id, QuestionFormDTO questionFormDTO) {
        //校验参数
        if (StringUtils.isBlank(questionFormDTO.getTitle()) || StringUtils.isBlank(questionFormDTO.getDescription())|| questionFormDTO.getAnonymity() == null) {
            throw new BadRequestException("参数错误");
        }
        InteractionQuestion question = getById(id);
        if (question == null) {
            throw new BadRequestException("id有误");
        }
        //判断是否是自己的，自己的才能修改
        if (!question.getUserId().equals(UserContext.getUser())) {
            throw new BadRequestException("无权限修改");
        }
        question.setTitle(questionFormDTO.getTitle());
        question.setDescription(questionFormDTO.getDescription());
        question.setAnonymity(questionFormDTO.getAnonymity());
        //更新
        updateById(question);
    }

    /**
     * 用户端分页查询提问
     * @param query
     * @return
     */
    @Override
    public PageDTO<QuestionVO> pageQuestion(QuestionPageQuery query) {
//        //获取用户信息
//        Long userId = UserContext.getUser();
//        //校验参数
//        if (query.getCourseId() == null){
//            throw new BadRequestException("课程id不能为空");
//        }
//        //分页查询
//        //Mybatis-Plus不查询某些字段如何处理
//        Page<InteractionQuestion> page = lambdaQuery().select(InteractionQuestion.class, info -> !info.getProperty().equals("description"))
//                .eq(query.getOnlyMine(), InteractionQuestion::getUserId, userId)
//                .eq(InteractionQuestion::getCourseId, query.getCourseId())
//                .eq(query.getSectionId() != null, InteractionQuestion::getSectionId, query.getSectionId())
//                .eq(InteractionQuestion::getHidden, false)
//                .page(query.toMpPageDefaultSortByCreateTimeDesc());
//        List<InteractionQuestion> records = page.getRecords();
//        if (CollectionUtils.isEmpty(records)){
//            return PageDTO.empty(page);
//        }
//        //Set<Long> userIds = new HashSet<>();
//        //Set<Long> lastAnswerIds = new HashSet<>();
//
//        //所有的最新问题id
//        Set<Long> lastAnswerIds = records.stream().filter(c -> c.getLatestAnswerId() != null)
//                .map(InteractionQuestion::getLatestAnswerId)
//                .collect(Collectors.toSet());
//
//        log.info("最新问题id,{}",lastAnswerIds);
//        //所有的提问者id，过滤掉匿名
//        Set<Long> userIds = records.stream().filter(c -> !c.getAnonymity())
//                .map(InteractionQuestion::getUserId)
//                .collect(Collectors.toSet());
//        log.info("提问者id,{}",userIds);
//        Map<Long,InteractionReply> replyMap = new HashMap<>();
//        if (CollUtils.isNotEmpty(lastAnswerIds)){
//            List<InteractionReply> replyList = replyService.listByIds(lastAnswerIds);
//            for (InteractionReply reply : replyList) {
//                replyMap.put(reply.getId(),reply);
//            }
//        }
//        //查询用户信息
//        List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
//        Map<Long, UserDTO> userMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, c -> c));
//
//
//        //封装返回结果
//        List<QuestionVO> vos = new ArrayList<>();
//        for (InteractionQuestion record : records) {
//            QuestionVO vo = BeanUtils.copyBean(record, QuestionVO.class);
//            if (!vo.getAnonymity()){
//                UserDTO userDTO = userMap.get(record.getUserId());
//                if (userDTO != null) {
//                    vo.setUserName(userDTO.getName());
//                    vo.setUserIcon(userDTO.getIcon());
//                }
//            }
//            InteractionReply reply = replyMap.get(record.getLatestAnswerId());
//            if (reply != null) {
//                if (!reply.getAnonymity()){
//                    vo.setLatestReplyUser(userMap.get(reply.getUserId()).getName());
//                    vo.setLatestReplyContent(reply.getContent());
//                }
//            }
//            vos.add(vo);
//        }
//        return PageDTO.of(page,vos);
        // 1.参数校验，课程id和小节id不能都为空
        Long courseId = query.getCourseId();
        Long sectionId = query.getSectionId();
        if (courseId == null && sectionId == null) {
            throw new BadRequestException("课程id和小节id不能都为空");
        }
        // 2.分页查询
        Page<InteractionQuestion> page = lambdaQuery()
                .select(InteractionQuestion.class, info -> !info.getProperty().equals("description"))
                .eq(query.getOnlyMine(), InteractionQuestion::getUserId, UserContext.getUser())
                .eq(courseId != null, InteractionQuestion::getCourseId, courseId)
                .eq(sectionId != null, InteractionQuestion::getSectionId, sectionId)
                .eq(InteractionQuestion::getHidden, false)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionQuestion> records = page.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }
        // 3.根据id查询提问者和最近一次回答的信息
        Set<Long> userIds = new HashSet<>();
        Set<Long> answerIds = new HashSet<>();
        // 3.1.得到问题当中的提问者id和最近一次回答的id
        for (InteractionQuestion q : records) {
            if(!q.getAnonymity()) { // 只查询非匿名的问题
                userIds.add(q.getUserId());
            }
            answerIds.add(q.getLatestAnswerId());
        }
        // 3.2.根据id查询最近一次回答
        answerIds.remove(null);
        Map<Long, InteractionReply> replyMap = new HashMap<>(answerIds.size());
        if(CollUtils.isNotEmpty(answerIds)) {
            List<InteractionReply> replies = replyMapper.selectBatchIds(answerIds);
            for (InteractionReply reply : replies) {
                replyMap.put(reply.getId(), reply);
                if(!reply.getAnonymity()){ // 匿名用户不做查询
                    userIds.add(reply.getUserId());
                }
            }
        }

        // 3.3.根据id查询用户信息（提问者）
        userIds.remove(null);
        Map<Long, UserDTO> userMap = new HashMap<>(userIds.size());
        if(CollUtils.isNotEmpty(userIds)) {
            List<UserDTO> users = userClient.queryUserByIds(userIds);
            userMap = users.stream()
                    .collect(Collectors.toMap(UserDTO::getId, u -> u));
        }

        // 4.封装VO
        List<QuestionVO> voList = new ArrayList<>(records.size());
        for (InteractionQuestion r : records) {
            // 4.1.将PO转为VO
            QuestionVO vo = BeanUtils.copyBean(r, QuestionVO.class);
            vo.setUserId(null);
            voList.add(vo);
            // 4.2.封装提问者信息
            if(!r.getAnonymity()){
                UserDTO userDTO = userMap.get(r.getUserId());
                if (userDTO != null) {
                    vo.setUserId(userDTO.getId());
                    vo.setUserName(userDTO.getName());
                    vo.setUserIcon(userDTO.getIcon());
                }
            }

            // 4.3.封装最近一次回答的信息
            InteractionReply reply = replyMap.get(r.getLatestAnswerId());
            if (reply != null) {
                vo.setLatestReplyContent(reply.getContent());
                if(!reply.getAnonymity()){// 匿名用户直接忽略
                    UserDTO user = userMap.get(reply.getUserId());
                    vo.setLatestReplyUser(user.getName());
                }

            }
        }

        return PageDTO.of(page, voList);
    }

    /**
     * 根据id查询问题详情
     * @param id
     * @return
     */
    @Override
    public QuestionVO getQuestionById(Long id) {
        //校验
        if (id==null){
            throw new BadRequestException("问题id不能为空");
        }
        InteractionQuestion question = getById(id);
        if (question == null) {
            throw new BadRequestException("问题不存在，请求问题id有误");
        }
        //如果该问题管理员设置了隐藏,返回空
        if (question.getHidden()){
            return null;
        }
        //获取提问者的用户id
        Long questionUserId = question.getUserId();
        QuestionVO vo = BeanUtils.copyBean(question, QuestionVO.class);
        //判断是否匿名，如果匿名提问者头像和昵称就不用返回
        //不是匿名用户
        if (!question.getAnonymity()){
            UserDTO userDTO = userClient.queryUserById(questionUserId);
            if (userDTO == null) {
                throw new BadRequestException("用户不存在");
            }
            vo.setUserName(userDTO.getName());
            vo.setUserIcon(userDTO.getIcon());
        }
        return vo;
    }

    /**
     * 删除我的问题
     * @param id
     */
    @Override
    public void deleteQuestion(Long id) {
        //获取当前用户
        Long userId = UserContext.getUser();
        //校验
        if (id==null){
            throw new BadRequestException("问题id不能为空");
        }
        InteractionQuestion question = getById(id);
        if (question == null) {
            throw new BadRequestException("问题不存在");
        }
        if (!question.getUserId().equals(userId)){
            throw new BadRequestException("不是该用户的问题");
        }
        //删除问题和问题下的回答以及评论
        Long questionId = question.getId();
        //删除问题
        removeById(id);
        //删除回答以及评论
        replyService.lambdaUpdate().eq(InteractionReply::getQuestionId, questionId).remove();
    }

    /**
     * 管理端分页查询问题
     * @param query
     * @return
     */
    //todo 这个接口好好看看
    @Override
    public PageDTO<QuestionAdminVO> adminPageQuestion(QuestionAdminPageQuery query) {
        List<Long> courseIds = null;
        //处理课程名称，得到课程id
        if (StringUtils.isNotBlank(query.getCourseName())){
            courseIds = searchClient.queryCoursesIdByName(query.getCourseName());
            if (CollectionUtils.isEmpty(courseIds)){
                return PageDTO.empty(0L,0L);
            }
        }
        Integer status = query.getStatus();
        LocalDateTime beginTime = query.getBeginTime();
        LocalDateTime endTime = query.getEndTime();
        Page<InteractionQuestion> page = lambdaQuery()
                .eq(courseIds != null, InteractionQuestion::getCourseId, courseIds)
                .eq(status != null, InteractionQuestion::getStatus, status)
                .between(beginTime != null && endTime != null, InteractionQuestion::getCreateTime, beginTime, endTime)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());

        List<InteractionQuestion> records = page.getRecords();
        if (CollUtils.isEmpty(records)){
            return PageDTO.empty(page);
        }
        //准备vo需要的数据
        Set<Long> userIds = new HashSet<>();
        Set<Long> cIds = new HashSet<>();
        Set<Long> cataIds = new HashSet<>();
        for (InteractionQuestion record : records) {
            userIds.add(record.getUserId());
            cIds.add(record.getCourseId());
            cataIds.add(record.getChapterId());
            cataIds.add(record.getSectionId());
        }
        //根据id查询用户
        List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
        Map<Long, UserDTO> userMap = new HashMap<>(userDTOS.size());
        if (CollUtils.isNotEmpty(userDTOS)){
           userMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, c -> c));
        }
        //根据id查询课程
        List<CourseSimpleInfoDTO> cInfos = courseClient.getSimpleInfoList(cIds);
        Map<Long, CourseSimpleInfoDTO> cInfoMap = new HashMap<>(cInfos.size());
        if (CollUtils.isNotEmpty(cInfos)){
            cInfoMap = cInfos.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, c -> c));
        }
        //根据id查询章节
        //todo 这段没看懂干嘛
        List<CataSimpleInfoDTO> catas = catalogueClient.batchQueryCatalogue(cataIds);
        Map<Long, CataSimpleInfoDTO> cataMap = new HashMap<>(catas.size());
        if (CollUtils.isNotEmpty(catas)){
            cataMap = catas.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, c -> c));
        }
        List<QuestionAdminVO> vos = new ArrayList<>(records.size());
        //封装vo返回
        for (InteractionQuestion record : records) {
            QuestionAdminVO vo = BeanUtils.copyBean(record, QuestionAdminVO.class);
            //设置用户属性
            UserDTO user = userMap.get(record.getUserId());
            if (user != null) {
                vo.setUserName(user.getName());
            }
            //设置课程属性
            CourseSimpleInfoDTO cInfo = cInfoMap.get(record.getCourseId());
            if (cInfo != null) {
                vo.setCourseName(cInfo.getName());
                vo.setCategoryName(categoryCache.getCategoryNames(cInfo.getCategoryIds()));
            }
            //设置章节信息
            //todo 这里有点问题
            vo.setChapterName(cataMap.get(record.getChapterId()).getName());
            vo.setSectionName(cataMap.get(record.getSectionId()).getName());
            //添加到集合
            vos.add(vo);
        }
        return PageDTO.of(page, vos);
    }
}
